package cn.js.sangu.unitStore.service.process;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.hutool.core.util.StrUtil;
import cn.js.sangu.unitStore.common.exception.ServiceException;
import cn.js.sangu.unitStore.dto.PartAttributeDTO;
import cn.js.sangu.unitStore.entity.BomDe;
import cn.js.sangu.unitStore.entity.CodeLib;
import cn.js.sangu.unitStore.entity.ExcelData;
import cn.js.sangu.unitStore.entity.User;
import cn.js.sangu.unitStore.service.CodeLibService;
import cn.js.sangu.unitStore.utils.TokenUtils;
import cn.js.sangu.unitStore.service.DicCzService;
import cn.js.sangu.unitStore.service.DicDzService;
import cn.js.sangu.unitStore.service.DicGgService;
import cn.js.sangu.unitStore.service.SettingService;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class AutoCodeProcessService {

    @Autowired
    CodeLibService codeLibService;

    @Autowired
    PartAttributesCheck partAttributesCheck;

    @Autowired
    private SettingService settingService;

    private static final ConcurrentHashMap<String, AtomicInteger> sequenceMap3 = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, AtomicInteger> sequenceMap4 = new ConcurrentHashMap<>();

    // 标准件前缀列表
    // private static final List<String> biaoZhunJianList = Arrays.asList(
    // "GB", "JB", "HG", "CB", "HB", "QC", "NB", "TB");
    private static final List<String> biaoZhunJianList = Arrays.asList(
            "GB/", "JB/", "HG/", "CB/", "HB/", "QC/", "NB/", "TB/",
            "GB／", "JB／", "HG／", "CB／", "HB／", "QC／", "NB／", "TB／");
    // 材质代号映射表
    private Map<String, String> caiZhiMap = new HashMap<>();
    // 规格代号映射表
    private Map<String, String> guiGeMap = new HashMap<>();
    // 定制标准件映射表
    private Map<String, String> initDzMap = new HashMap<>();

    // 新增：用于记录每个7-9位编码对应的最后一次变量A值（第一个小数点后的内容）
    private static final ConcurrentHashMap<String, Map.Entry<String, Integer>> lastVariableAMap3 = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map.Entry<String, Integer>> lastVariableAMap4 = new ConcurrentHashMap<>();

    // 初始化材质代号和规格代号 Map
    // public AutoCodeProcessService() {
    // // 可根据实际情况从数据库或配置文件中加载数据
    // this.caiZhiMap = CodeMapInit.initCaiZhiMap();
    // this.guiGeMap = CodeMapInit.initGuiGeMap();
    // this.initDzMap = CodeMapInit.initDzMap();
    // }

    // 初始化材质代号和规格代号 Map
    private final DicCzService dicCzService;
    private final DicDzService dicDzService;
    private final DicGgService dicGgService;

    public AutoCodeProcessService(DicCzService dicCzService, DicDzService dicDzService, DicGgService dicGgService) {
        this.dicCzService = dicCzService;
        this.dicDzService = dicDzService;
        this.dicGgService = dicGgService;
    }

    /**
     * 执行任务时更新Map数据（每次任务执行前调用）
     */
    public void updateMapsBeforeTask() {
        dicCzService.getCaiZhiList().forEach(item -> {
            String[] names = item.getName().split("、");
            for (String name : names) {
                String trimmedName = name.trim();
                if (!trimmedName.isEmpty()) {
                    this.caiZhiMap.put(trimmedName, item.getCode());
                }
            }
        });
        dicGgService.getGuiGeList().forEach(item -> {
            String[] names = item.getName().split("、");
            for (String name : names) {
                String trimmedName = name.trim();
                if (!trimmedName.isEmpty()) {
                    this.guiGeMap.put(trimmedName, item.getCode());
                }
            }
        });
        dicDzService.getDzList().forEach(item -> {
            String[] names = item.getName().split("、");
            for (String name : names) {
                String trimmedName = name.trim();
                if (!trimmedName.isEmpty() && !this.initDzMap.containsKey(trimmedName)) {
                    // 由于getDzList()已按priority降序排序，相同名称只保留第一个(优先级最高的)
                    this.initDzMap.put(trimmedName, item.getCode());
                }
            }
        });
        log.info("更新编码字典到Map完成");
    }

    // 新增清空序列号缓存方法
    public void clearSequenceMap() {
        try {
            // 添加同步锁确保线程安全
            synchronized (sequenceMap3) {
                sequenceMap3.clear();
                log.info("序列号缓存Map3已成功清空，当前缓存大小: {}", sequenceMap3.size());
            }
            synchronized (sequenceMap4) {
                sequenceMap4.clear();
                log.info("序列号缓存Map4已成功清空，当前缓存大小: {}", sequenceMap4.size());
            }
            updateMapsBeforeTask(); // 执行任务前更新数据
        } catch (Exception e) {
            log.error("清空序列号缓存时发生异常", e);
            throw new RuntimeException("清空序列号缓存失败", e);
        }
    }

    // 清理非数字字符
    private String cleanNumericString(String input) {
        if (input == null) {
            return "";
        }

        // 处理特殊格式：SJ4G.02.21.00G1-1346位
        if (input.contains(".") && input.contains("-")) {
            // 取出第一个小数点右边的内容
            String afterDot = input.substring(input.indexOf('.') + 1);
            // 取出第一个横杠之前的内容
            String beforeDash = afterDot.split("-")[0];
            // 去掉所有小数点
            return beforeDash.replace(".", "");
        }

        return input
                .replace('×', '0')
                .replaceAll("[A-Za-z]", "0") // 新增字母转0逻辑
                .replaceAll("[^0-9]", ""); // 最终保留纯数字
    }

    /**
     * 批量生成编码列表
     * 
     * @param dataList  Excel数据列表
     * @param creatorId 创建者ID（可选），当在非Web请求线程中调用时可以传入
     * @return 更新后的Excel数据列表
     */
    public List<ExcelData> generateCodeList(List<ExcelData> dataList, Integer creatorId) {
        clearSequenceMap();// 初始化lastVariableAMap
        // 筛选和排序后统一生成编码（仅当autoCode为true时执行）在写入Excel数据时调用方法生成物料编码逻辑和数据更准确
        for (ExcelData data : dataList) {
            if (data.getXitong().contains("跳过")) {
                log.info("====> 用户标注跳过：{}", data.getTuhao());
                continue;
            }

            String code = generateCode(data, creatorId, "清单筛选批量");
            log.info("====>自动生成code： [{}]", code);
            // data.setShuchu(code);
            data.setSyscode(code);
        }
        return dataList;
    }

    /**
     * 根据ExcelData对象生成编码
     * 
     * @param data      Excel数据对象
     * @param creatorId 创建者ID（必须显式传递）
     * @return 生成的编码
     */
    public String generateCode(ExcelData data, Integer creatorId, String remark) {
        BomDe bomDe = new BomDe();
        bomDe.setTuhao(data.getTuhao());
        bomDe.setName(data.getName());
        bomDe.setCailiao(data.getCailiao());
        bomDe.setGuige(data.getGuige());
        bomDe.setLeibie(data.getLeibie());
        bomDe.setBianma(data.getBianma());
        bomDe.setBeizhu(data.getBeizhu());
        return generateCode(bomDe, creatorId, remark);
    }

    /**
     * 获取BOM匹配模式配置
     * 
     * @return 匹配模式 (0:精准匹配, 1:模糊匹配)
     */
    private int getMatchMode() {
        try {
            Map<String, Object> settingsMap = settingService.getModuleSettingsMap("bom");
            if (settingsMap != null && settingsMap.containsKey("bom.match_mode")) {
                return Integer.parseInt(settingsMap.get("bom.match_mode").toString());
            }
        } catch (Exception e) {
            log.warn("获取匹配模式配置失败，使用默认模糊匹配", e);
        }
        return 1; // 默认模糊匹配
    }

    /**
     * 根据配置的匹配模式查找编码
     * 
     * @param name     物料名称
     * @param matchMap 匹配映射表
     * @return 匹配到的编码
     */
    private String findCodeByMatchMode(String name, Map<String, String> matchMap) {
        if (name == null || matchMap == null || matchMap.isEmpty()) {
            return null;
        }

        int matchMode = getMatchMode();

        // 精准匹配模式
        if (matchMode == 0) {
            return matchMap.get(name);
        }

        // 模糊匹配模式 (默认)
        // 先尝试精准匹配
        String exactMatch = matchMap.get(name);
        if (exactMatch != null) {
            return exactMatch;
        }

        // 再尝试模糊匹配
        for (String key : matchMap.keySet()) {
            if (name.contains(key)) {
                return matchMap.get(key);
            }
        }

        return null;
    }

    private void biaoZhunJian(StringBuilder code, String tuhao, String name, String cailiao, String guige,
            String beizhu) {
        // 第1位
        boolean startsWithStandard = biaoZhunJianList.stream()
                .anyMatch(prefix -> tuhao != null && tuhao.startsWith(prefix));
        // code.append(startsWithStandard ? '1' : '2');
        if (startsWithStandard) {
            code.append('1'); // 第1位 tuhao大部分都是GB开头
            code.append(caiZhiMap.getOrDefault(cailiao, "00")); // 第2至3位
            if (guige != null) {
                if (guige.contains("×") && guige.contains("-")) {
                    // 前5后4 少数情况
                    // 4-8位
                    String digits4to8 = cutTuhao(tuhao);
                    code.append(String.format("%05d", digits4to8.isEmpty() ? 0 : Integer.parseInt(digits4to8)));
                    // 处理guige中的数字(9-12位)
                    String digits9to12 = String.format("%04d",
                            Integer.parseInt(guige.split("-")[1].replaceAll("[^0-9]", "")));
                    code.append(digits9to12);
                } else {
                    // 前4后5 多数情况
                    // 处理第一个"/"或"／"之后和"-"之前的数字(4-7位)
                    String digits4to7 = cutTuhao(tuhao);
                    if (digits4to7.length() > 4) {
                        digits4to7 = digits4to7.substring(0, 4);
                    }
                    code.append(String.format("%04d", digits4to7.isEmpty() ? 0 : Integer.parseInt(digits4to7)));
                    // 处理guige中的数字(8-12位)
                    String digits8to12 = "?????";
                    if (guige.contains("×")) {
                        // 处理guige中的×符号
                        String[] parts = guige.split("×");
                        if (parts.length >= 2) {
                            String x = parts[0].replaceAll("[^0-9]", "");
                            if (x.length() == 1) {
                                x = "0" + x;
                            }
                            String y = parts[parts.length - 1].replaceAll("[^0-9]", "");
                            if (y.length() == 1) {
                                y = "0" + y;
                            }
                            String z = x + "0" + y;
                            if (z.length() > 5) {
                                log.warn("拼接后的数字[{}]长度超过5位,已尝试去除中间0", z);
                                z = x + y;
                            }
                            digits8to12 = String.format("%05d", Integer.parseInt(z));
                        }
                    } else {
                        String cleanedGuige = guige.replaceAll("[^0-9]", "");
                        digits8to12 = String.format("%05d", cleanedGuige.isEmpty() ? 0
                                : Integer.parseInt(cleanedGuige.substring(0, Math.min(5, cleanedGuige.length()))));
                    }
                    code.append(digits8to12);
                }
            } else {
                // 有时候guige为空，则从tuhao中取
                if (tuhao.contains("[")) {
                    String afterBracket = tuhao.substring(tuhao.indexOf('[') + 1);
                    String bracketBeforeDash;
                    if (afterBracket.contains("-")) {
                        bracketBeforeDash = afterBracket.split("-")[0];
                    } else if (afterBracket.contains("]")) {
                        bracketBeforeDash = afterBracket.split("]")[0];
                    } else {
                        bracketBeforeDash = afterBracket;
                    }
                    String digits8to12 = bracketBeforeDash.replaceAll("[^0-9]", "");
                    code.append(String.format("%05d", digits8to12.isEmpty() ? 0 : Integer.parseInt(digits8to12)));
                } else {
                    code.append("?????");
                }
            }
            // 13-14位
            if ("内六角圆柱头螺钉".equals(name)) {
                code.append("12");
            } else {
                code.append("00");
            }
        } else {
            code.append('2');
            // 第2至3位
            code.append(caiZhiMap.getOrDefault(cailiao, "00"));
            // 根据配置的匹配模式查找编码
            String result = findCodeByMatchMode(name, initDzMap);
            // code.append(result != null ? result : "???");// 第4至6位
            // 第4至6位
            if (result != null) {
                code.append(result);
            } else {
                // 第4-12位
                // 若guige中有9位数字，则作为code第4-12位。13-14位为00
                // 否则，若tuhao中能取出9位数字，则作为code第4-12位。13-14位为00
                Pattern nineDigitsPattern = Pattern.compile("\\d{9}");
                boolean found = false;

                // 先检查guige中是否有9位数字
                if (guige != null && !guige.isEmpty()) {
                    Matcher guigeMatcher = nineDigitsPattern.matcher(guige);
                    if (guigeMatcher.find()) {
                        code.append(guigeMatcher.group());
                        found = true;
                    }
                }

                // 如果guige中没有找到，则检查tuhao中是否有9位数字
                if (!found && tuhao != null && !tuhao.isEmpty()) {
                    Matcher tuhaoMatcher = nineDigitsPattern.matcher(tuhao);
                    if (tuhaoMatcher.find()) {
                        code.append(tuhaoMatcher.group());
                        found = true;
                    }
                }

                // 添加13-14位
                code.append("00");
            }
            // 正常情况前面只有6位，否则就是特殊情况,定制标准件格式特殊，1类别+2材料+5名称+2名称(内牙)+2(接管尺寸)+2(补位) = 14
            if (code.length() > 6) {
                if (code.length() == 8) {
                    // 第9-10位处理：从括号内容中判断内外牙和提取数字
                    Pattern bracketPattern = Pattern.compile("\\(([^\\)]+)\\)");
                    Matcher bracketMatcher = bracketPattern.matcher(name);
                    String bracketContent = "";

                    // 尝试获取第一个括号内的内容
                    if (bracketMatcher.find()) {
                        bracketContent = bracketMatcher.group(1);
                    }

                    // 初始化第9-10位为默认值"00"
                    StringBuilder ninthTenthDigits = new StringBuilder("00");

                    // 处理第9位：判断括号内容中的内外牙
                    if (bracketContent.contains("内牙")) {
                        ninthTenthDigits.setCharAt(0, '1');
                    } else if (bracketContent.contains("外牙")) {
                        ninthTenthDigits.setCharAt(0, '2');
                    }

                    // 处理第10位：提取括号内容中的第一个数字
                    Pattern digitPattern = Pattern.compile("\\d");
                    Matcher digitMatcher = digitPattern.matcher(bracketContent);
                    if (digitMatcher.find()) {
                        ninthTenthDigits.setCharAt(1, digitMatcher.group().charAt(0));
                    }

                    // 添加到编码中
                    code.append(ninthTenthDigits);

                    // 第11-12位处理：查找tuhao中的两位连续数字
                    Pattern twoDigitsPattern = Pattern.compile("\\d{2}");
                    Matcher twoDigitsMatcher = twoDigitsPattern.matcher(tuhao);
                    if (twoDigitsMatcher.find()) {
                        code.append(twoDigitsMatcher.group());
                    } else {
                        code.append("00");
                    }

                    // 第13-14位为固定00
                    code.append("00");
                } else if (code.length() == 7) {
                    // 提取逻辑：从tuhao中提取所有的数字字符
                    if (tuhao != null && !tuhao.isEmpty()) {
                        StringBuilder allDigits = new StringBuilder();
                        for (int i = 0; i < tuhao.length(); i++) {
                            char c = tuhao.charAt(i);
                            if (Character.isDigit(c)) {
                                allDigits.append(c);
                            }
                        }

                        // 如果提取到数字，则添加到编码中
                        if (allDigits.length() > 0) {
                            code.append(allDigits.toString());
                        }
                    }
                }
            } else {
                // 第7至14位
                if (tuhao != null && tuhao.split("-").length > 5) {
                    // 定义正则表达式，匹配数字
                    Pattern p = Pattern.compile("(\\d+)-(\\d+)-(\\d+)");
                    Matcher m = p.matcher(tuhao);
                    if (m.find()) {
                        code.append(m.group(1)).append(m.group(2)).append(m.group(3));
                    } else {
                        code.append("??????");
                    }
                    code.append("??");
                } else if (tuhao.split("-").length > 2) {
                    if (tuhao.matches(".*[\u4e00-\u9fa5]+.*")) { // tuhao包含汉字
                        if (tuhao.contains("分")) {
                            if (name.contains("多通") || name.contains("三通")) {
                                code.append("23"); // 7-8位
                            } else if (name.contains("水管") || name.contains("水龙头")) {
                                code.append("20"); // 7-8位
                            } else {
                                code.append("??");
                            }

                            if (StrUtil.isNotBlank(guige)) { // 规格存在就取规格
                                // 随便先给4个规格的数字，代表9-12位
                                String cleanedTuhao = guige.replaceAll("[^0-9]", "");
                                String fourDigits = String.format("%-4s", cleanedTuhao).replace(' ', '0').substring(0,
                                        4);
                                code.append(fourDigits);
                                code.append("00");// 13-14位
                            } else {
                                code.append("????00");// 9-14位
                            }
                        }
                    } else {
                        if (Arrays.stream(tuhao.split("-"))
                                .map(String::length)
                                .distinct()
                                .count() == 1 && areFirstThreePartsNumeric(tuhao.split("-"))) { // 三个以上的元素长度相同，且三个元素为纯数字
                            // if (tuhao.length()==11) {
                            String[] parts = tuhao.split("-");
                            try {
                                // 外径 - 处理首位可能包含的D字母
                                String outerStr = parts[0].startsWith("D") ? parts[0].substring(1) : parts[0];
                                int outerDiameter = Integer.parseInt(outerStr);
                                // 内径 (7-9位) - 处理首位可能包含的D字母
                                String innerStr = parts[1].startsWith("D") ? parts[1].substring(1) : parts[1];
                                int innerDiameter = Integer.parseInt(innerStr);
                                // 长度 (10-12位)
                                int length = Integer.parseInt(parts[2]);
                                // 厚度计算 (13-14位)
                                int thickness = (outerDiameter - innerDiameter) / 2;

                                code.append(String.format("%03d", innerDiameter)) // 7-9位: 内径
                                        .append(String.format("%03d", length)) // 10-12位: 长度
                                        .append(String.format("%02d", thickness)); // 13-14位: 厚度
                            } catch (NumberFormatException e) {
                                log.error("解析图号'{}'为数字时出错", tuhao, e);
                                code.append("????????????"); // 出错时填充占位符
                            }
                        } else if (name.contains("搭扣")) {
                            code.append("80"); // 7-8位 第三级分类：1门溶式，2推拉式，3焊接式，4拉紧式
                            code.append("0000");// 9-12位
                            if (tuhao.matches(".*\\d{2}$")) { // tuhao最后两位为数字
                                code.append(tuhao.substring(tuhao.length() - 2));
                            } else if (tuhao.matches(".*\\d$")) {
                                code.append("0").append(tuhao.substring(tuhao.length() - 1)); // 最后一位数字前补0
                            } else {
                                code.append("00"); // 默认00
                            }
                        } else if (tuhao.equals(guige)) {
                            if (name.contains("同步带轮") && guige.contains("M")) {
                                // 定义匹配的 Map
                                Map<String, String> mMap = new HashMap<>();
                                mMap.put("3M", "1");
                                mMap.put("5M", "2");
                                mMap.put("8M", "3");
                                mMap.put("14M", "4");
                                mMap.put("20M", "5");
                                // 提取 M 字母以及其左侧一位数字
                                int mIndex = guige.indexOf("M");
                                String a = "";
                                if (mIndex > 0) {
                                    a = guige.substring(mIndex - 1, mIndex + 1);
                                }
                                String code7 = mMap.getOrDefault(a, "0");
                                code.append(code7);

                                // 提取 guige 中的非数字字符
                                String b = guige.replaceAll("[^0-9]", "");
                                if (b.length() > 5) {
                                    b = b.substring(b.length() - 5);
                                } else {
                                    b = String.format("%05d", b.isEmpty() ? 0 : Integer.parseInt(b));
                                }
                                code.append(b);
                                code.append("00");// 13-14位
                            } else if (tuhao.equals(guige)) {
                                String digitsInGuige = guige.replaceAll("[^0-9]", "");
                                String code8to12;
                                if (digitsInGuige.length() < 5) {
                                    code8to12 = String.format("%05d",
                                            digitsInGuige.isEmpty() ? 0 : Integer.parseInt(digitsInGuige));
                                } else {
                                    code8to12 = digitsInGuige.substring(digitsInGuige.length() - 5);
                                }
                                if (code.length() < 7) {
                                    code.append("0");
                                }
                                code.append(code8to12);
                                // code.append("0").append(code8to12); // 假设第7位补0，然后追加8-12位
                                code.append("00"); // 13-14位
                            } else {
                                code.append("00000000"); // 7-14位
                            }
                        } else if (tuhao.contains("φ")) {
                            if (tuhao.split("-").length == 3) {
                                String temp = tuhao.replaceAll("[^0-9]", "");
                                String fiveDigits = temp.length() > 5 ? temp.substring(0, 5)
                                        : String.format("%05d", temp.isEmpty() ? 0 : Integer.parseInt(temp));
                                if (code.length() < 7) {
                                    code.append("0"); // 不足7位补0
                                }
                                code.append(fiveDigits); // 8-12位
                                code.append("00"); // 13-14位
                            } else if (tuhao.split("-").length == 4) {
                                String[] parts = tuhao.split("-");
                                StringBuilder e = new StringBuilder();
                                for (String part : parts) {
                                    String digits = part.replaceAll("[^0-9]", "");
                                    if (digits.length() > 2) {
                                        digits = digits.substring(0, 2);
                                    }
                                    e.append(digits);
                                }
                                String res = e.toString();
                                if (res.length() > 7) {
                                    res = res.substring(0, 7);
                                } else {
                                    res = String.format("%07d", Integer.parseInt(res));
                                }
                                code.append(res);
                            }
                        } else if (code.length() > 6) { // 前4后5
                            String[] parts = tuhao.split("-", 3);
                            if (parts.length == 3) {
                                String a = parts[0].replaceAll("[^0-9]", "");
                                String b = parts[1].replaceAll("[^0-9]", "");
                                String c = parts[2].replaceAll("[^0-9]", "");
                                String temp = a + b + c;
                                if (temp.length() < 5) {
                                    temp = a + "0" + b + "0" + c;
                                    if (temp.length() < 5) {
                                        temp = String.format("%-5s", temp).replace(' ', '0');
                                    } else {
                                        temp = temp.substring(0, 5);
                                    }
                                } else {
                                    temp = temp.substring(0, 5);
                                }
                                code.append(temp);
                            } else {
                                // 若分割后不足三部分，沿用原逻辑
                                String cleanedTuhao = tuhao.replaceAll("[^0-9]", "");
                                String fiveDigits = cleanedTuhao.length() > 5 ? cleanedTuhao.substring(0, 5)
                                        : String.format("%05d",
                                                cleanedTuhao.isEmpty() ? 0 : Integer.parseInt(cleanedTuhao));
                                code.append(fiveDigits);
                            }
                            code.append("00"); // 13-14位
                        } else {
                            // 7-12位
                            code.append("0");
                            String cleanedTuhao = tuhao.replaceAll("[^0-9]", "");
                            String fiveDigits = cleanedTuhao.length() > 5 ? cleanedTuhao.substring(0, 5)
                                    : String.format("%05d",
                                            cleanedTuhao.isEmpty() ? 0 : Integer.parseInt(cleanedTuhao));
                            code.append(fiveDigits);
                            // 13-14位
                            code.append("00");
                        }
                    }
                } else if (guige.contains("rpm") || guige.toLowerCase().contains("kw")) {
                    String power = "00"; // 默认功率值
                    String speed = "0000"; // 默认转速值
                    // 处理KW/kw功率值
                    if (guige.toLowerCase().contains("kw")) {
                        String kwPart = guige.substring(0, guige.toLowerCase().indexOf("kw"));
                        String powerDigits = kwPart.replaceAll("[^0-9.]", "");
                        if (!powerDigits.isEmpty()) {
                            // 处理小数情况，取前两位数字
                            powerDigits = powerDigits.replace(".", "");
                            power = powerDigits.length() >= 2 ? powerDigits.substring(0, 2)
                                    : String.format("%02d", Integer.parseInt(powerDigits));
                        }
                    }
                    // 处理rpm转速值
                    if (guige.contains("rpm")) {
                        // String rpmPart = guige.substring(0, guige.indexOf("rpm"));
                        int rpmIndex = guige.indexOf("rpm");
                        int lastNonDigitIndex = rpmIndex - 1;
                        // 从右向左找到最后一个非数字字符
                        while (lastNonDigitIndex >= 0 && Character.isDigit(guige.charAt(lastNonDigitIndex))) {
                            lastNonDigitIndex--;
                        }
                        String rpmPart = guige.substring(lastNonDigitIndex + 1, rpmIndex);
                        String speedDigits = rpmPart.replaceAll("[^0-9]", "");
                        if (!speedDigits.isEmpty()) {
                            speed = String.format("%04d", Integer.parseInt(speedDigits));
                        }
                    }
                    code.append(power) // 7-8位: 功率值
                            .append("00") // 9-10位: 固定00
                            .append(speed); // 11-14位: 转速值
                } else if (beizhu != null && initDzMap.keySet().stream().anyMatch(beizhu::contains)) {
                    // 取出匹配的initDzMap值作为7-8位
                    String dzValue = initDzMap.entrySet().stream()
                            .filter(entry -> beizhu.contains(entry.getKey()))
                            .findFirst()
                            .map(Map.Entry::getValue)
                            .orElse("00");
                    // 取出tuhao中的所有数字作为9-12位
                    String digits = tuhao.replaceAll("[^0-9]", "");
                    String fourDigits = String.format("%04d", digits.isEmpty() ? 0 : Integer.parseInt(digits));
                    code.append(dzValue) // 7-8位: initDzMap对应值
                            .append(fourDigits) // 9-12位: tuhao中的数字
                            .append("00"); // 13-14位: 固定00
                } else if (tuhao.length() < 6) {
                    if (tuhao.startsWith("D")) {
                        // 取出D字母之后和"."符号之前的数字
                        String numericPart = tuhao.substring(1).split("\\.")[0];
                        // 清理非数字字符并补足3位
                        String cleaned = numericPart.replaceAll("[^0-9]", "");
                        code.append(String.format("%03d", Integer.parseInt(cleaned.isEmpty() ? "0" : cleaned))); // 7-9位
                        if (code.length() == 9) { // 大部分情况此时是9位
                            code.append("000"); // 10-12位
                        } else {
                            code.append("00"); // 11-12位 少部分情况是10位(如4-6使用了4-7的4位)
                        }

                        code.append("00"); // 13-14位
                    } else if (tuhao.matches("\\d+")) { // tuhao全为数字
                        code.append("0"); // 第7位补0
                        String paddedTuhao = String.format("%05d", Integer.parseInt(tuhao));
                        code.append(paddedTuhao);
                        code.append("00"); // 13-14位
                    } else {
                        code.append("00000000"); // 7-14位
                    }
                } else if (tuhao.length() < 7) {
                    if (tuhao.equals(guige)) {
                        if (tuhao.matches(".*\\d{2}$")) { // 最后两位是数字
                            code.append("000000").append(tuhao.substring(tuhao.length() - 2)); // 7-12位补0，13-14位用最后两位
                        } else if (tuhao.matches(".*\\d$")) { // 最后一位是数字
                            code.append("0000000").append(tuhao.substring(tuhao.length() - 1)); // 7-13位补0，14位用最后一位
                        } else {
                            code.append("00000000"); // 7-14位
                        }
                    } else {
                        code.append("00000000"); // 7-14位
                    }
                } else if (code.toString().startsWith("211") && guige != null && guige.matches("\\d{2}")) { // 为特殊211定制
                    code.append("000000").append(guige); // 7-12位补0，13-14位用guige的最后两位
                } else if (tuhao.contains("-") && tuhao.equals(guige)) {
                    String temp;
                    if (tuhao.contains("×")) {
                        temp = tuhao.replace('×', '0').replaceAll("[^0-9]", "");
                    } else {
                        temp = tuhao.replace('-', '0').replaceAll("[^0-9]", "");
                    }
                    if (temp.length() > 5) {
                        temp = temp.substring(0, 5);
                    } else {
                        temp = String.format("%05d", Integer.parseInt(temp.isEmpty() ? "0" : temp));
                    }
                    // code.append("0");//7-8位
                    if (name.contains("调整")) {
                        code.append("1");
                    } else {
                        code.append("0");
                    }
                    code.append(temp); // 8-12位
                    code.append("00"); // 13-14位
                } else if (tuhao.startsWith("SJ4G") && guige != null && !tuhao.equals(guige)) {
                    if (guige.contains("-") && guige.split("-").length == 3) {
                        String[] parts = guige.replaceAll("[a-zA-Z]", "").split("-");
                        if (parts.length > 1) {
                            String a = String.format("%03d", Integer.parseInt(parts[0]));
                            String b = String.format("%03d", Integer.parseInt(parts[1]));
                            code.append(a).append(b); // 7-12位
                            code.append("00"); // 13-14位
                        } else {
                            code.append("00000000"); // 7-14位
                        }
                    } else if (name.contains("水管")) { // 特殊情况
                        code.append("1");// 7位
                        // 补充代码：处理guige中的数字
                        String temp = guige.replaceAll("[^0-9]", "");
                        String fiveDigits = temp.length() > 5 ? temp.substring(0, 5)
                                : String.format("%05d", temp.isEmpty() ? 0 : Integer.parseInt(temp));
                        code.append(fiveDigits); // 8-12位
                        code.append("00"); // 13-14位
                    } else {
                        code.append("00000000"); // 7-14位
                    }
                } else if (tuhao.startsWith("SPD1G")) {
                    // 取tuhao第一个小数点之后的内容
                    int dotIndex = tuhao.indexOf('.');
                    String a = dotIndex != -1 ? tuhao.substring(dotIndex + 1) : "";
                    // 若a的首位是0则忽略
                    while (a.startsWith("0")) {
                        a = a.substring(1);
                    }
                    // 忽略数字以外的字符
                    String digits = a.replaceAll("[^0-9]", "");
                    // 处理长度
                    String codePart;
                    if (digits.length() >= 5) {
                        codePart = digits.substring(0, 5);
                    } else {
                        codePart = String.format("%05d", Integer.parseInt(digits));
                    }
                    // 追加到code的7-11位
                    code.append(codePart);
                    code.append("000"); // 12-14位
                } else if (tuhao.contains("×")) {
                    String temp = tuhao.replace('×', '0');
                    // 忽略数字以外的符号
                    temp = temp.replaceAll("[^0-9]", "");
                    // 若此时 tuhao 大于 6 位，则取前 6 位，若不足 6 位则左侧补 0
                    String sixDigits = temp.length() > 6 ? temp.substring(0, 6)
                            : String.format("%06d", temp.isEmpty() ? 0 : Integer.parseInt(temp));
                    code.append(sixDigits);
                    code.append("00"); // 13-14位
                } else {
                    code.append("????????"); // 7-14位
                }
            }
            // 若code中连续有6个以上的0的情况，则将这连续0的位置标记出来，替换为时间戳的后N位
            // String codeStr = code.toString();
            // String time = String.format("%013d", System.currentTimeMillis()); //
            // 生成14位时间戳字符串
            // Pattern pattern = Pattern.compile("0{6,}"); // 匹配连续6个及以上的0
            // Matcher matcher = pattern.matcher(codeStr);
            // while (matcher.find()) {
            // int start = matcher.start();
            // int end = matcher.end();
            // int n = end - start; // 连续0的长度N
            // String timestampSuffix = time.substring(time.length() - n - 1); // 取时间戳后N位
            // code.replace(start, end, timestampSuffix); // 替换连续0为时间戳后N位
            // }
            // // 若有？代表没有匹配到的异常
            // if (codeStr.contains("?")) {
            // // System.out.println(time);
            // int questionIndex = codeStr.indexOf('?');
            // if (questionIndex > 0) {
            // String prefix = codeStr.substring(0, questionIndex);
            // int n = prefix.length();
            // if (n <= 14) {
            // code.setLength(0); // 清空code内容
            // code.append(prefix + time.substring(n - 1));
            // }
            // }
            // }
        }
    }

    private void feiBiaoJian(StringBuilder code, String tuhao, String name, String cailiao, String guige, String type) {
        // 第1位
        code.append('3');

        // 第2至3位
        // code.append(caiZhiMap.getOrDefault(cailiao, "00"));
        String result = caiZhiMap.get(cailiao);
        if (result == null) {
            for (Map.Entry<String, String> entry : caiZhiMap.entrySet()) {
                if (cailiao.contains(entry.getKey())) {
                    result = entry.getValue();
                    break;
                }
            }
        }
        code.append(result != null ? result : "00");
        // 第4至6位
        if (tuhao != null && tuhao.contains(".")) {
            String firstPart = tuhao.split("\\.")[0];
            code.append(guiGeMap.getOrDefault(firstPart, "???"));
        } else {
            code.append("???");
        }

        // 第7至11位（修改后核心逻辑）
        if (tuhao != null && tuhao.contains(".")) {
            // if (tuhao.equals("SJ4G.02.02.02.01")) {
            // log.info("debugger");
            // }
            // 从左向右取第一个小数点右边的内容（变量A）
            String afterFirstDot = tuhao.substring(tuhao.indexOf('.') + 1);
            // 新增：截取字母前的内容（处理currentA）
            String currentA = getBeforeLetterPart(afterFirstDot); // 第162行修改
            // 忽略小数点并去掉第一位0
            String cleaned = afterFirstDot.replace(".", "").replaceFirst("^0", "");
            if (cleaned.contains("G")) {
                // 分割字母G前的内容
                cleaned = cleaned.split("G")[0];
            }
            String codePart7To9;
            String codePart10To11;

            if (cleaned.length() >= 2) {
                // 取前3位作为7-9位，不足补0
                codePart7To9 = cleaned.length() >= 3 ? cleaned.substring(0, 3)
                        : cleaned + String.join("", Collections.nCopies(3 - cleaned.length(), "0"));

                if (cleaned.length() > 3) {
                    // 初始化计数器（基于7-9位）202
                    String baseKey = codePart7To9;

                    // 获取当前变量A和历史记录的变量A
                    Map.Entry<String, Integer> lastEntry = lastVariableAMap3.getOrDefault(baseKey,
                            new AbstractMap.SimpleEntry<>("", 0));
                    String lastA = lastEntry.getKey();
                    int lastGeneratedNumber = lastEntry.getValue(); // 新增：记录最后生成的序号

                    // 检查tuhao后三位是否包含G
                    // String lastThree = tuhao.substring(Math.max(0, tuhao.length() - 3));
                    // boolean containsG = lastThree.contains("G");

                    // 判断是否需要递增：包含G且当前A与历史A一致时不递增
                    // boolean shouldIncrement = !(containsG && currentA.equals(lastA));
                    // 事实上无论带不带G，只要完全一样都不需要递增
                    boolean shouldIncrement = !(currentA.equals(lastA));

                    // 计算10-11位（初始为01，递增时使用计数器值）
                    // codePart10To11 = shouldIncrement
                    // ? String.format("%02d", counter.getAndIncrement())
                    // : String.format("%02d", counter.get()); // 不递增时保持当前值

                    if (shouldIncrement) {
                        AtomicInteger counter = sequenceMap3.computeIfAbsent(baseKey, k -> new AtomicInteger(1));
                        int currentCount = counter.getAndIncrement();
                        // log.info(tuhao + " " + baseKey + " " + counter.get()+" "+data.toString());
                        codePart10To11 = String.format("%02d", currentCount);
                        lastGeneratedNumber = currentCount; // 更新最后生成的序号
                    } else {
                        codePart10To11 = String.format("%02d", lastGeneratedNumber); // 直接使用最后生成的序号
                        // codePart10To11 = String.format("%02d", counter.get());
                    }
                    // 更新变量A的历史记录
                    lastVariableAMap3.put(baseKey, new AbstractMap.SimpleEntry<>(currentA, lastGeneratedNumber));
                } else {
                    codePart10To11 = "00";
                }
            } else {
                // 不足2位的情况保持原逻辑
                codePart7To9 = "000";
                codePart10To11 = "00";
            }
            code.append(codePart7To9).append(codePart10To11);
        } else {
            code.append("?????"); // 无小数点时填充占位符
        }

        // 第12位
        switch (type) {
            case "钣金件":
                code.append('1');
                break;
            case "机加件":
                code.append('2');
                break;
            case "合金件":
                code.append('3');
                break;
            case "标准件":
                code.append('4');
                break;
            case "型材件":
                code.append('5');
                break;
        }

        // 第13至14位
        if (tuhao != null && !tuhao.isEmpty()) {
            // 修改后的正则表达式：匹配最后三位中的字母+数字组合
            java.util.regex.Matcher matcher = java.util.regex.Pattern.compile(".*([A-Za-z])(\\d{1,2})$")
                    .matcher(tuhao);
            if (matcher.find()) {
                String numbers = matcher.group(2); // 取出字母后的数字部分
                // 直接使用完整数字，不足两位补前导零
                code.append(String.format("%02d", Integer.parseInt(numbers)));
            } else {
                // 没有字母时设为00
                code.append("00");
            }
        } else {
            code.append("00");
        }
    }

    private void zuJian(StringBuilder code, String tuhao, String name, String cailiao) {
        // 第1位
        code.append('4');

        // 第2至3位
        code.append(caiZhiMap.getOrDefault(cailiao, "00"));

        // 第4至6位
        if (tuhao != null && tuhao.contains(".")) {
            String firstPart = tuhao.split("\\.")[0];
            code.append(guiGeMap.getOrDefault(firstPart, "???"));
        } else {
            code.append("???");
        }

        // 第7至9位
        if (tuhao != null && tuhao.contains(".")) {
            // if (tuhao.equals("SJ4G.02.21.00G1-1346位")) {
            // log.info("debugger");
            // }
            // 从左向右取第一个小数点右边的内容（变量A）
            String afterFirstDot = tuhao.substring(tuhao.indexOf('.') + 1);
            // 新增：截取字母前的内容（处理currentA）
            String currentB = getBeforeLetterPart(afterFirstDot);
            // 忽略小数点并去掉第一位0
            String cleaned = afterFirstDot.replace(".", "").replaceFirst("^0", "");
            String codePart7To9;
            String codePart10To12 = "000";

            if (cleaned.length() >= 2) {
                // 取前3位作为7-9位，不足补0
                codePart7To9 = cleaned.length() >= 3 ? cleaned.substring(0, 3)
                        : cleaned + String.join("", Collections.nCopies(3 - cleaned.length(), "0"));

                // 初始化计数器（基于7-9位）
                String baseKey = codePart7To9;

                Map.Entry<String, Integer> lastEntry = lastVariableAMap4.getOrDefault(baseKey,
                        new AbstractMap.SimpleEntry<>("", 0));
                String lastB = lastEntry.getKey();
                int lastGeneratedNumber = lastEntry.getValue(); // 新增：记录最后生成的序号

                boolean shouldIncrement = !(currentB.equals(lastB));

                if (shouldIncrement) {
                    AtomicInteger counter = sequenceMap4.computeIfAbsent(baseKey, k -> new AtomicInteger(0));
                    int currentCount = counter.getAndIncrement();
                    lastGeneratedNumber = currentCount; // 更新最后生成的序号
                }
                codePart10To12 = String.format("%03d", lastGeneratedNumber); // 直接使用最后生成的序号
                lastVariableAMap4.put(baseKey, new AbstractMap.SimpleEntry<>(currentB, lastGeneratedNumber));
            } else {
                // 不足2位的情况保持原逻辑
                codePart7To9 = "000";
                codePart10To12 = "000";
            }
            code.append(codePart7To9).append(codePart10To12);
        } else {
            code.append("??????"); // 无小数点时填充占位符
        }

        // 第13至14位
        if (tuhao != null && tuhao.length() > 0) {
            // 清理非数字字符
            String cleanedTuhao = cleanNumericString(tuhao);
            if (cleanedTuhao.length() > 0) {
                code.append(
                        String.format("%02d", Integer.parseInt(cleanedTuhao.substring(cleanedTuhao.length() - 1))));
            } else {
                code.append("00");
            }
        } else {
            code.append("00");
        }
    }

    private void zhengTai(StringBuilder code, String cailiao, String tuhao, String beizhu) {
        // 第1位
        code.append('5');
        // 第2至3位
        code.append(caiZhiMap.getOrDefault(cailiao, "00"));
        // 第4至6位
        if (tuhao != null && tuhao.contains(".")) {
            String firstPart = tuhao.split("\\.")[0];
            code.append(guiGeMap.getOrDefault(firstPart, "???"));
        } else {
            code.append("???");
        }
        // 第7至12位
        code.append("??????");
        // 第13至14位
        code.append(beizhu != null && !beizhu.isEmpty() ? "99" : "00");
    }

    /**
     * 主要入口：根据本行其他字段数据，生成物料编码
     */
    public String generateCode(BomDe bom, Integer creatorId, String remark) {
        String type = bom.getLeibie();
        String tuhao = bom.getTuhao();
        String cailiao = bom.getCailiao();
        String name = bom.getName();
        String guige = bom.getGuige();
        String beizhu = bom.getBeizhu();
        String leibie = bom.getLeibie();
        String bianma = bom.getBianma();
        if (StrUtil.isBlank(tuhao)) {
            // 图号为空，跳过编码，返回14位0
            return "00000000000000";
        }

        // 先检查codeLib中是否已存在相同属性的零件
        String existingCode = partAttributesCheck.beforeEncoding(tuhao, name, cailiao, guige, leibie);
        if (existingCode != null) {
            log.info("生成前检查：发现码库存在此零件，直接返回编码'{}'", existingCode);
            return existingCode;
        }

        StringBuilder code = new StringBuilder();
        if ("标准件".equals(type)) {
            biaoZhunJian(code, tuhao, name, cailiao, guige, beizhu);
        } else if ("机加件".equals(type) || "钣金件".equals(type) || "机加/钣金件".equals(type) || "合件".equals(type)
                || "机加工".equals(type)) {
            feiBiaoJian(code, tuhao, name, cailiao, guige, type);
        } else if ("组件".equals(type) || "组合件".equals(type)) {
            zuJian(code, tuhao, name, cailiao);
        } else if ("整台设备".equals(type)) {
            zhengTai(code, cailiao, tuhao, beizhu);
        }
        // 根据设置决定如何处理编码中的问号
        String res;
        String questionMarkHandle = settingService.getSettingValue("bom.question_mark_handle");
        if (questionMarkHandle == null || "1".equals(questionMarkHandle)) {
            // 默认或设置为1：替换问号为随机数
            res = generateRandomCode(code);
        } else if ("2".equals(questionMarkHandle)) {
            // 设置为2：替换问号为零
            res = replaceQuestionMarksWithZero(code);
        } else {
            // 设置为0：保留问号
            res = code.toString();
        }
        // 将questionMarkHandle作为参数传递给afterEncoding方法，避免重复查询设置
        String finalCode = partAttributesCheck.afterEncoding(res, questionMarkHandle);

        // 将新生成的编码保存到codeLib总码库中
        try {
            if (!"00000000000000".equals(finalCode)) {
                CodeLib codeLib = new CodeLib();
                codeLib.setTuhao(tuhao);
                codeLib.setName(name);
                codeLib.setCailiao(cailiao);
                codeLib.setGuige(guige);
                codeLib.setLeibie(leibie);
                // codeLib.setBeizhu(beizhu);
                codeLib.setSyscode(finalCode);
                codeLib.setBianma(bianma);
                codeLib.setState(1); // 设置状态为有效

                // 使用传入的creatorId，不再尝试从ThreadLocal获取
                if (creatorId != null) {
                    codeLib.setCreator(creatorId);
                } else {
                    // 如果没有传入creatorId，尝试从请求上下文获取
                    User user = TokenUtils.getCurrentUser();
                    if (user != null) {
                        codeLib.setCreator(user.getId());
                    } else {
                        log.warn("无法获取创建者ID，使用默认值");
                    }
                }

                codeLib.setBeizhu(remark);
                // 调用codeLibService保存
                partAttributesCheck.getCodeLibService().save(codeLib);
            }
        } catch (Exception e) {
            log.error("保存新编码到codeLib时发生异常：{}，编码={}", e.getMessage(), finalCode);
            // 保存失败不影响编码返回，只记录错误日志
        }
        return finalCode;
    }

    /**
     * 将代码中的所有问号(?)替换为随机数字(0-9)
     * 
     * @param code 包含问号占位符的代码字符串构建器
     * @return 替换后的随机码
     */
    private String generateRandomCode(StringBuilder code) {
        StringBuilder result = new StringBuilder(code.length());
        for (int i = 0; i < code.length(); i++) {
            char c = code.charAt(i);
            if (c == '?') {
                result.append((int) (Math.random() * 10));
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }

    /**
     * 将代码中的所有问号(?)替换为零(0)
     * 
     * @param code 包含问号占位符的代码字符串构建器
     * @return 替换后的代码
     */
    private String replaceQuestionMarksWithZero(StringBuilder code) {
        StringBuilder result = new StringBuilder(code.length());
        for (int i = 0; i < code.length(); i++) {
            char c = code.charAt(i);
            if (c == '?') {
                result.append('0');
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }

    // 截取字母前的内容（处理currentA）
    private String getBeforeLetterPart(String str) {
        if (str == null)
            return "";
        int firstLetterIndex = str.length(); // 默认取全文
        for (int i = 0; i < str.length(); i++) {
            if (Character.isLetter(str.charAt(i))) {
                firstLetterIndex = i;
                break;
            }
        }
        return str.substring(0, firstLetterIndex);
    }

    // 处理第一个"/"或"／"之后和"-"之前的数字
    private String cutTuhao(String tuhao) {
        String separator = tuhao.contains("/") ? "/" : "／";
        String afterSeparator = tuhao.substring(tuhao.indexOf(separator) + 1);
        String beforeDash = afterSeparator.split("-")[0];
        return beforeDash.replaceAll("[^0-9]", "");
    }

    // 检查前三个部分是否为纯数字（可能包含前导D）
    private boolean areFirstThreePartsNumeric(String[] parts) {
        if (parts.length < 3) {
            return false;
        }
        try {
            // 处理每个部分，去除前导D字母并尝试转换为整数
            for (int i = 0; i < 3; i++) {
                String part = parts[i].startsWith("D") ? parts[i].substring(1) : parts[i];
                Integer.parseInt(part);
            }
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    // 反向解析属性
    public PartAttributeDTO parseAttributes(String code) {
        if (code == null || code.isEmpty() || code.length() != 14) {
            throw new ServiceException("编码有误，请核对后再试！");
        }
        String leibie = String.valueOf(code.charAt(0));
        switch (leibie) {
            case "1":
            case "2":
                leibie = "标准件";
                break;
            case "3":
                leibie = "机加/钣金件";
                break;
            case "4":
                leibie = "组件";
                break;
            default:
                leibie = "未匹配";
                break;
        }

        // 提取第2-3位数字（索引1和2）
        String caizhi = code.substring(1, 3);

        // 在材质映射表中根据value查找key，取第一个匹配项
        for (Map.Entry<String, String> entry : caiZhiMap.entrySet()) {
            if (caizhi.equals(entry.getValue())) {
                caizhi = entry.getKey();
            }
        }

        PartAttributeDTO dto = new PartAttributeDTO();
        dto.setLeibie(leibie);
        dto.setCailiao(caizhi);
        dto.setTuhao("敬请期待");
        dto.setName("敬请期待");
        dto.setGuige("敬请期待");
        return dto;
    }

}